﻿#include "../../ctlHandle.h"
#include "../../control.h"
#include "../../interface/IUserDraw.h"
#include "../../x/draw/draw.h"
#include <algorithm>

namespace swui
{
	template<typename TQ>
	static void _get_button_point(
		TQ* object, ctlTriangleDirection direction, 
		float widthPercent, float heightPercent, PointF *pt)
	{
		PointF center(object->getWidth() / 2.0f, 
			object->getHeight() / 2.0f);
		PointF percent(object->getWidth() * widthPercent, 
			object->getHeight() * heightPercent);
		switch(direction)
		{
		case ctlTriangleDirection::left:
			pt[0].X = center.X - percent.X / 2.0f;
			pt[0].Y = center.Y;
			pt[2].X = pt[1].X = pt[0].X + percent.X;
			pt[1].Y = center.Y - percent.Y / 2.0f;
			pt[2].Y = pt[1].Y + percent.Y;
			break;
		case ctlTriangleDirection::top:
			pt[0].X = center.X;
			pt[0].Y = center.Y - percent.Y / 2.0f;
			pt[1].X = center.X - percent.X / 2.0f;
			pt[2].Y = pt[1].Y = pt[0].Y + percent.Y;
			pt[2].X = pt[1].X + percent.X;
			break;
		case ctlTriangleDirection::right:
			pt[0].X = center.X + percent.X / 2.0f;
			pt[0].Y = center.Y;
			pt[2].X = pt[1].X = pt[0].X - percent.X;
			pt[1].Y = center.Y - percent.Y / 2.0f;
			pt[2].Y = pt[1].Y + percent.Y;
			break;
		case ctlTriangleDirection::bottom:
			pt[0].X = center.X;
			pt[0].Y = center.Y + percent.Y / 2.0f;
			pt[1].X = center.X - percent.X / 2.0f;
			pt[2].Y = pt[1].Y = pt[0].Y - percent.Y;
			pt[2].X = pt[1].X + percent.X;
			break;
		}
	}

	ctlRoot::lamNotifyEvent createTriangleButtonHandle(
		ctlTriangleDirection direction, 
		float widthPercent, float heightPercent, 
		ctlColor triangleColorFill, ctlColor triangleColorBorder, 
		decltype(ctlNotifyUserDraw::state) state)
	{
		return ctlRoot::lamNotifyEvent(
			[=](ctlRoot* object, ctlNotifyEvent* notify)
		{
			ctlNotifyUserDraw* userDrawInfo = static_cast<ctlNotifyUserDraw*>(notify->info);
			if(userDrawInfo->state != state) return;
			PointF pt[3];
			_get_button_point(object, direction, widthPercent, heightPercent, pt);
			for(PointF& point : pt)
			{
				point.X += object->getLeft();
				point.Y += object->getTop();
			}
			Graphics* graphics = static_cast<Graphics*>(userDrawInfo->graphics);
			SolidBrush brush(MAKE_COLOR32(triangleColorFill));
			graphics->FillPolygon(&brush, pt, 3, FillModeAlternate);
			if(triangleColorBorder != triangleColorFill)
			{
				Pen pen(MAKE_COLOR32(triangleColorBorder));
				graphics->DrawPolygon(&pen, pt, 3);
			}
		} );
	}

	ctlRoot::lamNotifyEvent createTriangleButtonHandle(
		ctlTriangleDirection direction, 
		float widthPercent, float heightPercent, 
		ctlColor triangleColorFil, 
		decltype(ctlNotifyUserDraw::state) state)
	{
		return createTriangleButtonHandle(
			direction, widthPercent, heightPercent, 
			triangleColorFil, triangleColorFil, state);
	}
	ctlPoint _get_alignment_point(ctlRoot::moveAlignment, ctlRect);
	ctlRoot::lamNotifyEvent createTriangleButtonHandle(
		ctlTriangleDirection direction, 
		float widthPercentx, float heightPercentx,
		int xOffset, int yOffset,
		ctlColor triangleColorFill, ctlColor triangleColorBorder, 
		bool sizeIsAbsolute, ctlRoot::moveAlignment alignment,
		decltype(ctlNotifyUserDraw::state) state)
	{
		return ctlRoot::lamNotifyEvent(
			[=](ctlRoot* object, ctlNotifyEvent* notify)
		{
			ctlNotifyUserDraw* userDrawInfo = static_cast<ctlNotifyUserDraw*>(notify->info);
			if(userDrawInfo->state != state) return;

			float widthPercent = widthPercentx, heightPercent = heightPercentx;
			if(sizeIsAbsolute)
			{
				heightPercent /= object->getHeight();
				widthPercent /= object->getWidth();
			}
			
			ctlPoint this_pt = _get_alignment_point(alignment, object->getRect());
			this_pt.x -= object->getLeft(), this_pt.y -= object->getTop();
			ctlPoint tri_ptx(static_cast<int>(object->getWidth() * widthPercent), 
				static_cast<int>(object->getHeight() * heightPercent));
			ctlRect rc(0, 0, tri_ptx.x, tri_ptx.y);
			ctlPoint tri_pt = _get_alignment_point(alignment, rc);
			ctlPoint result(this_pt.x - tri_pt.x + xOffset + object->getLeft(), 
				this_pt.y - tri_pt.y + yOffset + object->getTop());
			PointF pt[3];
			_get_button_point(&rc, direction, 1.0f, 1.0f, pt);
			for(PointF& elem : pt)
				elem.X += result.x, elem.Y += result.y;

			Graphics* graphics = static_cast<Graphics*>(userDrawInfo->graphics);
			SolidBrush brush(MAKE_COLOR32(triangleColorFill));
			graphics->FillPolygon(&brush, pt, 3, FillModeAlternate);
			if(triangleColorBorder != triangleColorFill)
			{
				Pen pen(MAKE_COLOR32(triangleColorBorder));
				graphics->DrawPolygon(&pen, pt, 3);
			}
		});
	}
	ctlRoot::lamNotifyEvent createTriangleButtonHandle(
		ctlTriangleDirection direction, 
		float widthPercent, float heightPercent,
		int xOffset, int yOffset, ctlColor triangleColorFill, 
		bool bf, ctlRoot::moveAlignment alignment,
		decltype(ctlNotifyUserDraw::state) state)
	{
		return createTriangleButtonHandle(
			direction, widthPercent, heightPercent, 
			xOffset, yOffset, triangleColorFill,
			triangleColorFill, bf, alignment, state);
	}
}